
print <<EOF;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% abstract predicates:

%% type(?Type)
%% fun(?FName, ?Type, ?[Type])

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% concrete predicates:

%% language(?Lang)
%% Lang: prod(?Cat, ?CFun, ?[Cat])
%% Lang: coerce(?Cat, ?Cat)
%% Lang: lindef(?Cat, ?CFun)
%% Lang: lindef(?CFun, ?[Seq], ?Type)
%% Lang: lin(?CFun, ?[Seq], ?FName)
%% Lang: seq(?Seq, [?Item])
%%    where Item ::= lit(?J,?K) | cat(?J,?K) | 'atom'
%% Lang: categories(?Type, [?Cat])

%% Not implemented yet: 
%%    printnames(...)
%%    pre-terminals

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

:- discontiguous language/1.

EOF


while (<>) {
  chop; s/\s+/ /g;
  s/^ //; s/ $//; s/ ;$/;/;

  if (/^\}?$/) {
    # skip empty lines
  } elsif (/^abstract (\w+) {$/) {
    $abs = $1;
    print "\n%% abstract: $abs\n\n";
  } elsif (/^concrete (\w+) {$/) {
    $cnc = $1;
    print "\n%% concrete: $cnc\n";
    print "\nlanguage('$cnc').\n";
  } elsif (/^flag startcat = "(\w+)";$/) {
    $start = "'$1'";
    if (! $startcat{$start}) {
      print "starttype($start).\n";
    }
    $startcat{$start}++;
  } elsif (/^cat (\w+);$/) {
    print "type('$1').\n";
  } elsif (/^(?:fun|data) (\w+) : (.*);$/) {
    $fun = $1; 
    @typing = split / *-> */, $2;
    $restype = pop @typing;
    print "fun('$fun', '$restype', [" . join(",", map("'$_'", @typing)) . "]).\n";
  } elsif (/^\w+$/) {
    print "\n%% $_\n\n";
  } elsif (/^(C\d+) -> (F\d+)(\[[C\d,]*\])$/) {
    $cat = lc($1); $cfun = lc($2); $args = lc($3);
    print "'$cnc': prod($cat, $cfun, $args).\n";
  } elsif (/^(C\d+) -> _\[(C\d+)\]$/) {
    $cat = lc($1); $arg = lc($2);
    print "'$cnc': coerce($cat, $arg).\n";
  } elsif (/^(C\d+) -> (F\d+)$/) {
    $cat = lc($1); $cfun = lc($2); 
    print "'$cnc': lindef($cat, $cfun).\n";
  } elsif (/^(F\d+) := \(([S\d,]+)\) \[([\w ]+)\]$/) {
    $cfun = lc($1); $lin = lc($2); $name = $3;
    $pred = ($name =~ s/^(lindef) //) ? "lindef" : "lin";
    print "'$cnc': $pred($cfun, [$lin], '$name').\n";
  } elsif (/^(\w+) := range \[C(\d+) \.\. C(\d+)\]$/) {
    $type = $1;
    $range = join(",", map {"c$_"} ($2..$3));
    print "'$cnc': categories('$type', [$range]).\n";
  } elsif (/^(S\d+) := ?(.*)$/) {
    $seq = lc($1); $_ = $2;
    
    s/(["}>]) (["{<]|pre)/$1,$2/g; 
    s/\bpre (\{.+?\})/&convert_pre($1)/ge;
    s/{/lit(/g; s/}/)/g;
    s/</cat(/g; s/>/)/g;
    s/'/\\'/g; s/"/'/g; s/ /','/g;
    print "'$cnc': seq($seq, [$_]).\n";
  } elsif (/^(labels \[)?"[\w(){};= ]*"\]?$/) {
    # skip labels
  } else {
    print STDERR "%% UNKNOWN: $_\n";
    print "%% UNKNOWN: $_\n";
  }

}

sub convert_pre {
  local $_ = shift;
  s/\{/pre(\[/;
  s/; /,/;
  s/\}/\]\])/;
  s/" "/","/g;
  s/ \/ /:\[/g;
  s/; /\],/g;
  return $_;
}
